package com.rt.easyjava.common.base;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.rt.easyjava.common.utils.others.StringUtils;
import com.rt.easyjava.common.utils.others.SwitchLineCamel;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MyQueryWrapper {


    /**
     * 1, 多对一关联查询时，当查询条件中字段在多表中都存在时，给字段加别名，如：
     *    select * from table1 t1 left join table2 t2 on t1.id=t2.table1_id where t1.deleteflag=1
     * 2, 排除controller中自定义查询字段，以自定义查询条件为准，如 like查询等
     * @param o
     * @param ignoreColumnNames
     * @return
     */
    public static QueryWrapper buildQueryWrapper(Object o, String ... ignoreColumnNames){
        QueryWrapper queryWrapper=new QueryWrapper();

        //Field[] fields=o.getClass().getDeclaredFields();

        // 取父类属性
        List<Field> fieldList = new ArrayList<>() ;
        Class tempClass = o.getClass();
        while (tempClass != null) {//当父类为null的时候说明到达了最上层的父类(Object类).
            fieldList.addAll(Arrays.asList(tempClass .getDeclaredFields()));
            tempClass = tempClass.getSuperclass(); //得到父类,然后赋给自己
            if (tempClass == Model.class){
                tempClass = null;
            }
        }

        //for(int i=0;i<fields.length;i++){
        //    Field field = fields[i];
        for (Field field: fieldList) {
            TableField fieldAnnotation = field.getAnnotation(TableField.class);
            // 非数据库字段
            if (fieldAnnotation!=null && !fieldAnnotation.exist()) {
                continue;
            }

            //获取属性的名字、值
            String name = field.getName();
            String columnName = SwitchLineCamel.switch2Column(name);
            // in ignore list
            if (Arrays.asList(ignoreColumnNames).contains(columnName)) {
                continue;
            }
            if (Arrays.asList(ignoreColumnNames).contains(name)) {
                continue;
            }
            Object value = getFieldValueByName(name,o);

            if (StringUtils.isNull(value)) {
                continue;
            }
            queryWrapper.eq("t1."+columnName, value);

        }

        return queryWrapper;
    }


    /**
     * 根据属性名获取属性值
     * @param fieldName
     * @param o
     * @return
     */
    private static Object getFieldValueByName(String fieldName, Object o) {
        try {
            String firstLetter = fieldName.substring(0, 1).toUpperCase();
            String getter = "get" + firstLetter + fieldName.substring(1);
            Method method = o.getClass().getMethod(getter, new Class[] {});
            Object value = method.invoke(o, new Object[] {});
            return value;
        } catch (Exception e) {
            return null;
        }
    }

}
